package com.cml.batisext.core.repository.mybatis.base;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.cml.batisext.core.bean.base.IdEntity;
import com.cml.batisext.core.repository.mybatis.annotations.DbField;
import com.cml.batisext.util.DateUtil;
import com.google.common.collect.Lists;

/**
 * Sql Provider，用于调用通用Dao方法时，生成sql
 * 
 * @author Administrator
 *
 */
public abstract class BaseDaoSqlProvider {

	public static final ThreadLocal<Class<?>> currentResultBeanClass = new ThreadLocal<Class<?>>();
	
	@SuppressWarnings("unchecked")
	public String buildSql(Object param)throws Exception{
		
		//获取当前线程所需的bean类型
		Class<?> beanType = getCurrentResultBeanClass();
		
		if(param instanceof Map){
			return doBuildSql((Map<String,Object>)param,beanType);
		}else{
			return doBuildSql(param,beanType);
		}
	}
	
	public String doBuildSql(Map<String,Object> param , Class<?> beanType)throws Exception{
		return null;
	}
	
	public String doBuildSql(Object param , Class<?> beanType)throws Exception{
		return null;
	}
	
	public static Class<?> getCurrentResultBeanClass(){
		Class<?> clazz = currentResultBeanClass.get();
		currentResultBeanClass.set(null);
		return clazz;
	}
	
	/**
	 * 根据字段类型获取字段名称
	 * @param field 类属性的Field对象
	 * @param dbField 实体属性上的DbField标注
	 * @return
	 */
	protected static String getColumnName(Field field,DbField dbField){
		if(!dbField.column().equals("")){
			return "`"+dbField.column()+"`";
		}
		
		return "`"+field.getName()+"`";
	}
	
	/**
	 * 根据字段类型获取字段类型
	 * @param field 类属性的Field对象
	 * @param dbField 实体属性上的DbField标注
	 * @return
	 */
	protected static Class<?> getColumnType(Field field,DbField dbField){
		if(dbField.type() != Object.class){
			return dbField.type();
		}
		
		return field.getType();
	}
	
	/**
	 * 根据实体CLass对象，获取实体里所有的数据库字段对象
	 * @param beanType
	 * @return
	 */
	protected List<Field> getAllDbField(Class<?> beanType) {
		Field beanField[] = beanType.getDeclaredFields();
		List<Field> beanFields = Lists.newArrayList(beanField);
		
		while((beanType = beanType.getSuperclass()) != Object.class){
			beanFields.addAll(Lists.newArrayList(beanType.getDeclaredFields()));
		}
		
		return beanFields;
	}
	
	/**
	 * 根据字段类型获取字段名称
	 * 
	 * @param param 实体类型的一个实例
	 * @param field 类属性的Field对象
	 * @param dbField 实体属性上的DbField标注
	 * @return
	 */
	protected static Object getColumnValue(Object param,Field field,Class<?> beanType) throws Exception{

		StringBuffer sb = new StringBuffer(field.getName());
		sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
		Object value = null;
		try {
			Method getMethod = beanType.getMethod("get"+sb.toString());
			value = getMethod.invoke(param);
		} catch (Exception e) {
			value = field.get(param);
		}
		if(value instanceof String){
			String str = value.toString();
			str = str.replaceAll("'", "''");
			str = str.replaceAll("\\\\","\\\\\\\\");
			value = str;
		}
		return value;
	}
	
	/**
	 * 获取实体的主键值
	 * 
	 * 主键字段固定为id
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	protected Long getPKValue(Object param) throws  Exception {
		return (Long)IdEntity.class.getMethod("getId").invoke(param);
	}
	
	/**
	 * 根据类型，将实体的值转换为数据库Sql中的表示方式
	 * 
	 * 如 abc 在sql中表示为 'abc'
	 * 
	 * @param columnType 字段类型
	 * @param fieldValue 字段值
	 * @return
	 * @throws Exception
	 */
	protected String setupFieldValue(Class<?> columnType, Object fieldValue) throws Exception {
		if(fieldValue == null){
			return "null";
		}
		if(columnType == String.class){
			return "'"+fieldValue+"'";
		}
        if (columnType == Date.class) {
        	return "'"+DateUtil.dateTime2String((Date)fieldValue)+"'";
        }
		if(columnType == Date.class){
			return "'"+DateUtil.dateTime2String((Date)fieldValue)+"'";
		}
		if(columnType == Long.class || columnType == long.class || columnType == Double.class || columnType == int.class || columnType == double.class || columnType == float.class || columnType == Integer.class || columnType == Float.class){
			return fieldValue+"";
		}
		throw new Exception("不支持的字段类型:"+columnType.getSimpleName());
	}
	
}
